package com.example.sharding.config;

import com.alibaba.druid.pool.DruidDataSource;
import com.example.sharding.sharding.ProductInfoShardingAlgorithm;
import org.apache.shardingsphere.api.config.sharding.ShardingRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.TableRuleConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.InlineShardingStrategyConfiguration;
import org.apache.shardingsphere.api.config.sharding.strategy.StandardShardingStrategyConfiguration;
import org.apache.shardingsphere.shardingjdbc.api.ShardingDataSourceFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

@Configuration
public class DataSourceConfig {

    @Value("${datasource1.url}")
    private String url1;
    @Value("${datasource1.username}")
    private String username1;
    @Value("${datasource1.password}")
    private String password1;
    @Value("${datasource1.driver-class-name}")
    private String driverClassName1;

    @Value("${datasource2.url}")
    private String url2;
    @Value("${datasource2.username}")
    private String username2;
    @Value("${datasource2.password}")
    private String password2;
    @Value("${datasource2.driver-class-name}")
    private String driverClassName2;

    @Value("${spring.datasource.druid.filters}")
    private String filters;

    @Bean("dataSource")
    public DataSource dataSource() {
        try {
            DruidDataSource dataSource1 = new DruidDataSource();
            dataSource1.setDriverClassName(this.driverClassName1);
            dataSource1.setUrl(this.url1);
            dataSource1.setUsername(this.username1);
            dataSource1.setPassword(this.password1);
            dataSource1.setFilters(this.filters);

            DruidDataSource dataSource2 = new DruidDataSource();
            dataSource2.setDriverClassName(this.driverClassName2);
            dataSource2.setUrl(this.url2);
            dataSource2.setUsername(this.username2);
            dataSource2.setPassword(this.password2);
            dataSource2.setFilters(this.filters);

            //分库设置
            Map<String, DataSource> dataSourceMap = new HashMap<>(2);
            //添加两个数据库database0和database1
            dataSourceMap.put("ds1", dataSource1);
            dataSourceMap.put("ds2", dataSource2);


            // 配置 product_info 表规则
            TableRuleConfiguration userRuleConfiguration = new TableRuleConfiguration("product_info", "ds${1..2}.product_info_${1..2}");
            // 行表达式分表规则
            userRuleConfiguration.setTableShardingStrategyConfig(new InlineShardingStrategyConfiguration("productInfoId", "product_info_${product_info_id % 2 +1}"));
            // 行表达式分库规则
            userRuleConfiguration.setDatabaseShardingStrategyConfig(new InlineShardingStrategyConfiguration("productInfoId", "ds_${product_info_id % 2 + 1}"));
            // Sharding全局配置
            ShardingRuleConfiguration shardingRuleConfiguration = new ShardingRuleConfiguration();
            shardingRuleConfiguration.getTableRuleConfigs().add(userRuleConfiguration);

            // 创建数据源
            DataSource dataSource = ShardingDataSourceFactory.createDataSource(dataSourceMap, shardingRuleConfiguration, new Properties());
            return dataSource;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }

}
